﻿using NUnit.Framework;
using Sasa.QualityTools.CodeAnalysis.SearchEngine.Tests.Unit.Instruments;
using System;

namespace Sasa.QualityTools.CodeAnalysis.SearchEngine.Tests.Unit
{
    [TestFixture]
    public class QueryCompilerTest
    {
        private QueryCompiler<string> testee;


        [SetUp]
        public void SetUp()
        {
            this.testee = new QueryCompiler<string>(new WordCompiler());
        }

        [Test]
        public void TestCompileWithWord()
        {
            var actual = this.testee.Compile("o");
            Assert.IsTrue(actual("foo"));
            Assert.IsFalse(actual("bar"));
        }

        [Test]
        public void TestCompileWithAndStatement()
        {
            var actual = this.testee.Compile("f AND o");
            Assert.IsTrue(actual("foo"));
            Assert.IsFalse(actual("fff"));
            Assert.IsFalse(actual("ooo"));
            Assert.IsFalse(actual("bar"));
        }

        [Test]
        public void TestCompileWithAbbrevedAndStatement()
        {
            var actual = this.testee.Compile("f o");
            Assert.IsTrue(actual("foo"));
            Assert.IsFalse(actual("fff"));
            Assert.IsFalse(actual("ooo"));
            Assert.IsFalse(actual("bar"));
        }

        [Test]
        public void TestCompileWithOrStatement()
        {
            var actual = this.testee.Compile("f OR o");
            Assert.IsTrue(actual("foo"));
            Assert.IsTrue(actual("fff"));
            Assert.IsTrue(actual("ooo"));
            Assert.IsFalse(actual("bar"));
        }

        [Test]
        public void TestCompileWithAndOrStatement()
        {
            var actual = this.testee.Compile("f AND o OR x");
            Assert.IsTrue(actual("foo"));
            Assert.IsFalse(actual("fff"));
            Assert.IsFalse(actual("ooo"));
            Assert.IsFalse(actual("bar"));
            Assert.IsTrue(actual("xxx"));
            Assert.IsTrue(actual("fx"));
        }

        [Test]
        public void TestCompileWithParentheticAndOrStatement()
        {
            var actual = this.testee.Compile("f AND (o OR x)");
            Assert.IsTrue(actual("foo"));
            Assert.IsFalse(actual("fff"));
            Assert.IsFalse(actual("ooo"));
            Assert.IsFalse(actual("bar"));
            Assert.IsFalse(actual("xxx"));
            Assert.IsTrue(actual("fx"));
        }
    }
}
